/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.jfonia.model.elements;

import org.jfonia.connect5.basics.BasicValueNode;
import org.jfonia.connect5.basics.MutableValueNode;
import org.jfonia.connect5.basics.Observer;

/**
 *
 * @author Rik Bauwens
 */
public class KeySignature extends MusicalElement implements IStaffElement
{
	//private static final int[] sharps = {3, 0, 4, 1, 5, 2, 6}; //F, C, G, D, A, E, B
	//private static final int[] flats  = {6, 2, 5, 1, 4, 0, 3}; //B, E, A, D, G, C, F
        private static final int[] sharps = {10, 7, 11, 8, 5, 9, 6}; //F, C, G, D, A, E, B
	private static final int[] flats  = {6, 9, 5, 8, 4, 7, 3}; //B, E, A, D, G, C, F

        private MutableValueNode<Integer> typeNode; //Number of sharps (+) or flats (-)
	private int[] mods;

        public KeySignature()
        {
                this(0);
        }

        public KeySignature(int difference)
        {
                super(difference);
                typeNode = new BasicValueNode<Integer>(0);
                typeNode.addObserver(new Observer()
                {
                        public void onNotify(Object source)
                        {
                                /*mods = new int[7];
                                for (int i=0; i<7; i++)
                                        mods[i] = 0;
                                if (typeNode.getValue() > 0) //Sharps
                                {
                                        for (int i=0; i<typeNode.getValue(); i++)
                                                mods[sharps[i]] = 1;
                                }
                                else if (typeNode.getValue() < 0) //Flats
                                {
                                        for (int i=0; i<-typeNode.getValue(); i++)
                                                mods[flats[i]] = -1;
                                }*/
                            mods = new int[getAccidentalCount()];
                            if(typeNode.getValue() < 0)
                                    System.arraycopy(flats, 0, mods, 0, getAccidentalCount());
                            else
                                    System.arraycopy(sharps, 0, mods, 0, getAccidentalCount());
                        }
                });
        }

        public KeySignature setType(int type)
        {
                typeNode.setValue(type);
                return this;
        }

	public int getType()
	{
		return typeNode.getValue();
	}

	public int getAccidentalCount()
	{
		return Math.abs(typeNode.getValue());
	}

	/**
	 * Returns the modifier of a given reduced rank.
	 * @param rr reduced rank or diatonic pitch class (0=C, 1=D, ..., 5=B)
	 * @return 0=natural, 1=sharp, -1=flat ...
	 */
	public int getAccidental(int rr)
	{
		return mods[rr];
	}

        public MutableValueNode<Integer> getTypeNode()
        {
                return typeNode;
        }

        @Override
        public KeySignature clone(){
            KeySignature keySignature = new KeySignature(getDifference());
            keySignature.setType(typeNode.getValue());
            return keySignature;
        }
}
